package sv.gob.mh.dgii.dao.cat;


import sv.gob.mh.dgii.common.Utils;
import sv.gob.mh.dgii.dao.hibernate.HibernateDaoImpl;
import sv.gob.mh.dgii.model.TbListasValorDet;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.metadata.ClassMetadata;
import org.springframework.stereotype.Repository;

@Repository
public class TbListasValorDetDaoImpl extends HibernateDaoImpl implements TbListasValorDetDao {

	Log log = LogFactory.getLog(TbListasValorDetDaoImpl.class);

	public TbListasValorDetDaoImpl() {
		super(TbListasValorDet.class);
	}

	@SuppressWarnings("unchecked")
        @Override
	public List<TbListasValorDet> getListado(String lista, String modulo) {
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(getClazz());
		detachedCriteria.add(Restrictions.eq("id.clista", lista)).add(
				Restrictions.eq("id.cmodulo", modulo));
		detachedCriteria.add(Restrictions.isNull("ffin"));		
		return executeCriteria(detachedCriteria);
	}
	
	@SuppressWarnings("unchecked")
        @Override
	public List<TbListasValorDet> getListadoOrderBy(String lista, String modulo,String orderBy) {
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(getClazz());
		detachedCriteria.add(Restrictions.eq("id.clista", lista)).add(
				Restrictions.eq("id.cmodulo", modulo));
		detachedCriteria.add(Restrictions.isNull("ffin"));
		
		if(!Utils.isNullOrEmpty(orderBy)){
			detachedCriteria.addOrder(Order.asc(orderBy));
		}
				
		return executeCriteria(detachedCriteria);
	}

	@SuppressWarnings("unchecked")
        @Override
	public List<TbListasValorDet> getListadoSortByDescriptionDesc(String lista, String modulo) {
		DetachedCriteria dc = DetachedCriteria.forClass(getClazz());
		dc.add(Restrictions.eq("id.clista", lista)).add(Restrictions.eq("id.cmodulo", modulo));
		dc.add(Restrictions.isNull("ffin")); 
		dc.addOrder(Order.desc("dlistaDet"));		
		return executeCriteria(dc);
	}

        @SuppressWarnings("unchecked")
        @Override
	public List find(Object example) {

		return getByExample(example);
	}
        
	@SuppressWarnings("unchecked")
        @Override
	public List<TbListasValorDet> getByExampleSystem(TbListasValorDet model, Integer systemValue) {
		Criteria dc = getSessionFactory().getCurrentSession()
				.createCriteria(getClazz());

		if (!Utils.isNullOrEmpty(model.getId())) {
			if (!Utils.isNullOrEmpty(model.getId().getClista())) {
				dc.add(Restrictions.eq("id.clista", model.getId().getClista()));
			}
			if (!Utils.isNullOrEmpty(model.getId().getCmodulo())) {
				dc.add(Restrictions.eq("id.cmodulo", model.getId().getCmodulo()));
			}
			if (!Utils.isNullOrEmpty(model.getId().getClistaDet())) {
				dc.add(Restrictions.eq("id.clistaDet", model.getId().getClistaDet()));
			}

		}
		if (!Utils.isNullOrEmpty(model.getCvalor())) {
			dc.add(Restrictions.eq("cvalor", model.getCvalor()));
		}
		if (!Utils.isNullOrEmpty(model.getCusuario())) {
			dc.add(Restrictions.eq("cusuario", model.getCusuario()));
		}
		if (!Utils.isNullOrEmpty(model.getCvalor1())) {
			dc.add(Restrictions.eq("cvalor1", model.getCvalor1()));
		}
		if (!Utils.isNullOrEmpty(model.getCvalor2())) {
			dc.add(Restrictions.eq("cvalor2", model.getCvalor2()));
		}
		if (!Utils.isNullOrEmpty(model.getDlistaDet())) {
			dc.add(Restrictions.ilike("dlistaDet", model.getDlistaDet(), MatchMode.ANYWHERE));
		}

		if (!Utils.isNullOrEmpty(model.getExcludedValues())
				&& (model.getExcludedValues().size() > 0)) {
			dc.add(Restrictions.not(Restrictions.in("id.clista", model.getExcludedValues())));
		}
		if (!Utils.isNullOrEmpty(model.getIncludedValues())
				&& (model.getIncludedValues().size() > 0)) {
			dc.add(Restrictions.in("id.clista", model.getIncludedValues()));
		}
		if (!Utils.isNullOrEmpty(model.getCvalorDate())) {
			dc.add(Restrictions.gt("cvalorDate", model.getCvalorDate()));
		}
		if (!Utils.isNullOrEmpty(model.getCvalorNumber())
				&& !model.getCvalorNumber().equals(new Double(0))) {
			dc.add(Restrictions.eq("cvalorNumber", model.getCvalorNumber()));
		}
		if (!Utils.isNullOrEmpty(systemValue)) {
			dc.createCriteria("tbListasValor").add(Restrictions.eq("systemValue", systemValue));
		}

		return dc.list();
	}

        @SuppressWarnings("unchecked")
        @Override
	public List getByExample(Object example) {
		Criteria dc = getSessionFactory().getCurrentSession()
				.createCriteria(getClazz());
		TbListasValorDet model = (TbListasValorDet) example;

		if (!Utils.isNullOrEmpty(model.getId())) {
			if (!Utils.isNullOrEmpty(model.getId().getClista())) {
				dc.add(Restrictions.eq("id.clista", model.getId().getClista()));
			}
			if (!Utils.isNullOrEmpty(model.getId().getCmodulo())) {
				dc.add(Restrictions.eq("id.cmodulo", model.getId().getCmodulo()));
			}
			if (!Utils.isNullOrEmpty(model.getId().getClistaDet())) {
				dc.add(Restrictions.eq("id.clistaDet", model.getId().getClistaDet()));
			}
		}
		if (!Utils.isNullOrEmpty(model.getCvalor())) {
			dc.add(Restrictions.eq("cvalor", model.getCvalor()));
		}
		if (!Utils.isNullOrEmpty(model.getCusuario())) {
			dc.add(Restrictions.eq("cusuario", model.getCusuario()));
		}
		if (!Utils.isNullOrEmpty(model.getCvalor1())) {
			dc.add(Restrictions.eq("cvalor1", model.getCvalor1()));
		}
		if (!Utils.isNullOrEmpty(model.getCvalor2())) {
			dc.add(Restrictions.eq("cvalor2", model.getCvalor2()));
		}
		if (!Utils.isNullOrEmpty(model.getDlistaDet())) {
			dc.add(Restrictions.ilike("dlistaDet", model.getDlistaDet(), MatchMode.ANYWHERE));
		}
		if (!Utils.isNullOrEmpty(model.getExcludedValues())
				&& (model.getExcludedValues().size() > 0)) {
			dc.add(Restrictions.not(Restrictions.in("id.clista", model.getExcludedValues())));
		}
		if (!Utils.isNullOrEmpty(model.getIncludedValues())
				&& (model.getIncludedValues().size() > 0)) {
			dc.add(Restrictions.in("id.clista", model.getIncludedValues()));
		}
		if (!Utils.isNullOrEmpty(model.getCvalorDate())) {
			dc.add(Restrictions.gt("cvalorDate", model.getCvalorDate()));
		}
		if (!Utils.isNullOrEmpty(model.getCvalorNumber())
				&& !model.getCvalorNumber().equals(new Double(0))) {
			dc.add(Restrictions.eq("cvalorNumber", model.getCvalorNumber()));
		}

		return dc.list();
	}

        @SuppressWarnings("unchecked")
        @Override
	public List<TbListasValorDet> getListadoIn(List<String> codigos, String modulo, String lista) {
		DetachedCriteria dc = DetachedCriteria.forClass(getClazz());
		dc.add(Restrictions.eq("id.clista", lista)).add(Restrictions.eq("id.cmodulo", modulo)).add(
				Restrictions.in("id.clistaDet", codigos));
		List<TbListasValorDet> lst = executeCriteria(dc);
		return lst;
	}

        @SuppressWarnings("unchecked")
        @Override
	public List<TbListasValorDet> getListadoNotIn(List<String> codigos, String modulo, String lista) {
		DetachedCriteria dc = DetachedCriteria.forClass(getClazz());
		dc.add(Restrictions.eq("id.clista", lista)).add(Restrictions.eq("id.cmodulo", modulo)).add(
				Restrictions.not(Restrictions.in("id.clistaDet", codigos)));
		List<TbListasValorDet> lst = executeCriteria(dc);
		return lst;
	}

        @SuppressWarnings("unchecked")
        @Override
	public String getListaValorDetUnique(String module, String lista, String listaDet) {
		String returnValue = "";
		Object[] parameters = new Object[] { returnValue, module, lista, listaDet };

		try {
			returnValue = (String) executeFunction(
					"{ ? = call PKG_SIIT_FUNCTIONS.getListadoDetUniqueValor(?,?,?) }", parameters);
		} catch (Exception e) {
			log.error("No se pudo calcular PKG_SIIT_FUNCTIONS.getListadoDetUniqueValor()" + e);
			throw new RuntimeException(e);
		}
		return returnValue;
	}

        @SuppressWarnings("unchecked")
        @Override
	public String getListaValorDet(String module, String lista) {
		String returnValue = "";
		Object[] parameters = new Object[] { returnValue, module, lista };

		try {
			returnValue = (String) executeFunction(
					"{ ? = call PKG_SIIT_FUNCTIONS.getListadoDetValor(?,?) }", parameters);
		} catch (Exception e) {
			log.error("No se pudo calcular PKG_SIIT_FUNCTIONS.getListadoDetValor()" + e);
			throw new RuntimeException(e);
		}
		return returnValue;
	}

        @SuppressWarnings("unchecked")
        @Override
	public List<TbListasValorDet> getListadoRoles(TbListasValorDet model) {
		Criteria dc = getSessionFactory().getCurrentSession()
				.createCriteria(getClazz());
		if (!Utils.isNullOrEmpty(model.getId().getClista())) {
			dc.add(Restrictions.eq("id.clista", model.getId().getClista()));
		}
		if (!Utils.isNullOrEmpty(model.getId().getCmodulo())) {
			dc.add(Restrictions.eq("id.cmodulo", model.getId().getCmodulo()));
		}
		if (!Utils.isNullOrEmpty(model.getCvalor1())) {
			dc.add(Restrictions.eq("cvalor1", model.getCvalor1()));
		}
		if (!Utils.isNullOrEmpty(model.getCvalorNumber())
				&& !model.getCvalorNumber().equals(new Double(0))) {
			dc.add(Restrictions.gt("cvalorNumber", model.getCvalorNumber()));
		}
		return dc.list();
	}

        @SuppressWarnings("unchecked")
        @Override
	public TbListasValorDet getListaValorDet(TbListasValorDet tbListasValorDet) {
		return (TbListasValorDet) getFirstFromList(getByExample(tbListasValorDet));
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<TbListasValorDet> getListadoByModulo(String modulo, String clista) {
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(getClazz());
        detachedCriteria.add(Restrictions.eq("id.cmodulo", modulo));
        detachedCriteria.add(Restrictions.eq("id.clista", clista));
        return executeCriteria(detachedCriteria);
    }

    @Override
    public List getPage(int page, int pageSize, String sortProperty, String sortDirection, String modulo, String clista) {
        DetachedCriteria dc = DetachedCriteria.forClass(getClazz());
        Criteria c = dc.getExecutableCriteria(getSessionFactory().getCurrentSession());
        ClassMetadata meta = getSessionFactory().getClassMetadata(getClazz());
        // agregando filtro de modulo
        c.add(Restrictions.eq("id.cmodulo", modulo));
        if (clista != null) {
            c.add(Restrictions.eq("id.clista", clista));
        }
        // continua como en getPage de la clase HibernateDaoImpl
        c.setFirstResult((page - 1) * pageSize);
        c.setMaxResults(pageSize);

        if (Utils.isNullOrEmpty(sortProperty)) {
            sortProperty = meta.getIdentifierPropertyName();
        }
        if (Utils.isNullOrEmpty(sortDirection)) {
            sortDirection = "asc";
        }

        if ("desc".equalsIgnoreCase(sortDirection)) {
            c.addOrder(Order.desc(sortProperty));
        } else {
            c.addOrder(Order.asc(sortProperty));
        }

        return c.list();
    }
    
    @Override
    //Cuenta el numero total de registros de una tabla (con filtros)
    public Number getAllCount(String modulo, String clista) {
    	DetachedCriteria dc = DetachedCriteria.forClass(getClazz());
    	Criteria c = dc.getExecutableCriteria(getSessionFactory().getCurrentSession());
        c.add(Restrictions.eq("id.cmodulo", modulo));
        if (clista != null) {
            c.add(Restrictions.eq("id.clista", clista));
        }
        c.setProjection(Projections.rowCount());
        Number count = (Number) c.uniqueResult();
        //c.setProjection(proj);
        //c.setResultTransformer(transformer);
        return count;
	}
        
}